import {delay, designComponent, globalWatch, onBeforeUnmount, onMounted, reactive} from "@peryl/react-compose";
import {createEffects} from "@peryl/utils/createEffects";

export const RollingNumber = designComponent({
  name: 'rolling-number',
  props: {
    val: { type: Number }
  },
  setup({ props }) {

    const state = reactive({ val: 0 });

    const utils = {
      update: (space = 1) => {
        // console.log('update');
        space = Math.abs(space);
        const val = state.val;
        if (props.val == null) {
          state.val = 0;
          return;
        }
        if (val == props.val) {
          return;
        }
        if (val > props.val) {
          state.val = Math.max(val - space, props.val);
          delay(20).then(() => utils.update(space));
        } else {
          state.val = Math.min(val + space, props.val);
          delay(20).then(() => utils.update(space));
        }
      },
      format: (num: number) => {
        const [prepend, append] = String(num).split('.');
        const list = String(prepend).split('').reverse();
        const lastIndex = list.length - 1;
        return list.reduce((prev, item, index) => {
          return (lastIndex != index && (index + 1) % 3 == 0 ? ',' : '') + item + prev;
        }, '') + (!append ? '' : `.${append}`);
      },
    };

    const { effects } = createEffects();

    onMounted(() => {
      effects.push(
        globalWatch(() => props.val, () => {
          const curVal = state.val || 0;
          const newVal = props.val == null ? 0 : props.val;
          const space = Math.ceil((newVal - curVal) / 50);
          utils.update(space);
        }, { immediate: true })
      );
    });

    onBeforeUnmount(effects.clear);

    return () => (
      props.val != null && (
        <span>{utils.format(state.val)}</span>
      )
    );
  },
});
